<template>
    <div>
        <el-form label-width="auto">
            <div class="params-form-gray params">
                <el-form-item label="关联单据编码" prop="loanedBillCode">
                    <el-input v-model="params.loanedBillCode" placeholder="请输入" />
                </el-form-item>
                <el-form-item label="科目" prop="subjectId">
                    <el-cascader v-model="params.subjectId" :options="subjectChildList" style="flex: 1;"
                        :props="{ label: 'subjectName', value: 'subjectId' }" :show-all-levels="false" />
                </el-form-item>
                <el-form-item label="发生时间" prop="date">
                    <el-date-picker v-model="params.date" type="daterange" start-placeholder="开始时间"
                        end-placeholder="结束时间" value-format="YYYY-MM-DD" />
                </el-form-item>
                <el-form-item label="添加方式" prop="source">
                    <el-select v-model="params.source">
                        <el-option :value="0" label="系统生成"></el-option>
                        <el-option :value="1" label="手动添加"></el-option>
                    </el-select>
                </el-form-item>
                <span></span>
                <el-form-item>
                    <el-button type="primary" :icon="Search" @click="init">查询</el-button>
                    <el-button type="primary" plain :icon="RefreshRight" @click="reset">重置</el-button>
                </el-form-item>
            </div>
        </el-form>
        <div class="opeater">
            <div class="left">
                <el-button type="primary" plain @click="exportData">导出</el-button>
                <el-button type="primary" plain @click="batchAccounting">批量记账</el-button>
                <el-button type="primary" plain @click="updateVisible = true">更改科目</el-button>
                <el-button type="primary" @click="openModal">新建</el-button>
            </div>
            <div class="right">
                <el-input placeholder="根据姓名电话查询" v-model="params.partnerValue" @keyup.enter="init" @blur="init">
                    <template #prepend>
                        <el-select v-model="params.partnerType" placeholder="请选择" @change="init" style="width: 115px">
                            <el-option v-for="item, index in type" :label="item" :value="Number(index)" />
                        </el-select>
                    </template>
                </el-input>
                <el-button type="primary" plain :icon="RefreshRight" @click="resetKey">重置</el-button>
            </div>
        </div>
        <div class="table">
            <el-table :data="data" style="width: 100%" max-height="calc(100vh - 460px)"
                @selection-change="handleSelectionChange">
                <el-table-column type="selection" width="40" />
                <el-table-column prop="loanedBillCode" label="记账编码" width="180" />
                <el-table-column prop="addDate" label="发生时间" width="200" />
                <el-table-column prop="partnerName" label="合作方" min-width="200">
                    <template #default="scope">
                        {{ type[scope.row.partnerType] }}-{{ scope.row.partnerName }}
                    </template>
                </el-table-column>
                <el-table-column prop="remark" label="备注说明" width="300" />
                <el-table-column prop="address" label="凭证" width="240">
                    <template #default="scope">
                        <div>
                            <div v-for="item in scope.row.subjects">{{ ['借', '贷'][item.type - 1] }} : {{
                        item.subjectName
                    }}￥{{ item.money }}</div>
                        </div>
                    </template>
                </el-table-column>
                <el-table-column prop="orderCode" label="关联单据" width="240">
                    <template #default="scope">
                        <template v-if="scope.row.slipCode">
                            订单：<div class="link"
                                @click="toPath({ slipCode: scope.row.slipCode, type: scope.row.slipType })">
                                {{
                        scope.row.slipCode }}</div>
                        </template>
                        <span v-else>--</span>
                    </template>
                </el-table-column>
                <el-table-column label="添加方式" width="120">
                    <template #default="scope">
                        {{ ['系统生成', '手动添加'][scope.row.source] }}
                    </template>
                </el-table-column>
                <el-table-column prop="createBy" label="添加人" width="180">
                    <template #default="scope">
                        {{ scope.row.createBy || '系统生成' }}
                    </template>
                </el-table-column>
                <el-table-column label="操作" fixed="right" width="130">
                    <template #default="scope">
                        <el-button type="primary" link size="small" v-if="scope.row.source"
                            @click="openModal(scope.row)">编辑</el-button>
                        <el-button type="primary" link size="small" v-if="scope.row.source"
                            @click="openDel(scope.row)">删除</el-button>
                        <span v-else>--</span>
                    </template>
                </el-table-column>
                <template #empty>
                    <el-empty />
                </template>
            </el-table>
        </div>
        <div class="pagination">
            <el-pagination v-model:current-page="query.current" v-model:page-size="query.size"
                :page-sizes="[10, 20, 50, 100]" layout="total, sizes, prev, pager, next, jumper" :total="total"
                @size-change="init" @current-change="init" />
        </div>
        <el-dialog v-model="visible" width="540" center align-center @close="close">
            <template #header>
                <custom-title :title="(isNew ? '新建' : '编辑') + '记账记录'" />
            </template>
            <el-form :model="form" label-width="auto" :rules="rules" ref="formRef">
                <el-form-item label="关联合作方" prop="partnerId">
                    <div class="params-select">
                        <el-select v-model="form.partnerType" placeholder="请选择" style="width: 115px">
                            <el-option v-for="item, index in type" :label="item" :value="Number(index)" />
                        </el-select>
                        <el-select-v2 v-model:model-value="form.partnerId" filterable remote
                            :remote-method="remoteMethod" clearable :options="collaboratorsList" :props="{
                        label: 'name',
                        value: 'partnerId'
                    }" placeholder="请输入名称" />
                    </div>
                </el-form-item>
                <el-form-item label="发生额" props="subjects">
                    <div class="subject">
                        <div>
                            <div>借方</div>
                            <div class="list">
                                <div v-for="item, index in form.borrow">
                                    <el-form ref="borrowRef" :model="item" :rules="subjectRules">
                                        <el-form-item prop="subjectId">
                                            <el-select v-model="item.subjectId" placeholder="请选择" style="width: 150px">
                                                <template #header>
                                                    <input class="search-input" type="text" v-model="searchKey"
                                                        placeholder="请输入"><el-icon>
                                                        <Search />
                                                    </el-icon>
                                                </template>
                                                <el-option
                                                    v-for="subject in subjectChildList.filter(v => v.subjectName.indexOf(searchKey) != -1)"
                                                    :label="subject.subjectName" :value="subject.subjectId" />
                                            </el-select>
                                        </el-form-item>
                                        <el-form-item prop="money">
                                            <el-input placeholder="请输入金额" v-model="item.money">
                                            </el-input>
                                        </el-form-item>
                                    </el-form>
                                    <img src="../../../assets/images/del.png" alt=""
                                        @click="form.borrow?.splice(index, 1)">
                                </div>
                                <div class="add">
                                    <el-space @click="form.borrow?.push({ subjectId: '', money: '' })">
                                        <el-icon>
                                            <CirclePlusFilled />
                                        </el-icon>添加
                                    </el-space>
                                </div>
                            </div>
                        </div>
                        <div>
                            <div>贷方</div>
                            <div class="list">
                                <div v-for="item, index in form.loan">
                                    <el-form :model="item" ref="loanRef" :rules="subjectRules">
                                        <el-form-item prop="subjectId">
                                            <el-select v-model="item.subjectId" placeholder="请选择" style="width: 150px">
                                                <template #header>
                                                    <input class="search-input" type="text" v-model="searchKey"
                                                        placeholder="请输入"><el-icon>
                                                        <Search />
                                                    </el-icon>
                                                </template>
                                                <el-option
                                                    v-for="subject in subjectChildList.filter(v => v.subjectName.indexOf(searchKey) != -1)"
                                                    :label="subject.subjectName" :value="subject.subjectId" />
                                            </el-select>
                                        </el-form-item>
                                        <el-form-item prop="money">
                                            <el-input placeholder="请输入金额" v-model="item.money">
                                            </el-input>
                                        </el-form-item>
                                    </el-form>
                                    <img src="../../../assets/images/del.png" alt=""
                                        @click="form.loan?.splice(index, 1)">
                                </div>
                                <div class="add">
                                    <el-space @click="form.loan?.push({ subjectId: '', money: '' })">
                                        <el-icon>
                                            <CirclePlusFilled />
                                        </el-icon>添加
                                    </el-space>
                                </div>
                            </div>
                        </div>
                    </div>
                </el-form-item>
                <el-form-item label="关联单据" prop="slipId">
                    <div class="params-select">
                        <el-select v-model="form.slipType" placeholder="请选择" style="width: 115px" @change="getSlipList">
                            <el-option v-for="item, index in slipType" :label="item" :value="Number(index)" />
                        </el-select>
                        <el-select v-model="form.slipId" placeholder="请选择" style="width: 150px">
                            <template #header>
                                <input class="search-input" type="text" v-model="searchKey" placeholder="请输入"><el-icon>
                                    <Search />
                                </el-icon>
                            </template>
                            <el-option v-for="slip in slipList" :label="slip.slipCode" :value="slip.slipId" />
                        </el-select>
                    </div>
                </el-form-item>
                <el-form-item label="备注说明" prop="remark">
                    <el-input type="textarea" v-model="form.remark" placeholder="请输入"></el-input>
                </el-form-item>
            </el-form>
            <template #footer>
                <div>
                    <el-button @click="visible = false">取消</el-button>
                    <el-button type="primary" @click="comfirm">确定</el-button>
                </div>
            </template>
        </el-dialog>
        <el-dialog v-model="updateVisible" :width="600" center align-center :show-close="false" @close="resetUpdate">
            <template #header>
                <custom-title title="添加记账记录" />
            </template>
            <el-form :model="updadeForm" label-width="auto" ref="updadeFormRef" :rules="updadeRules">
                <el-form-item label="调整后科目" prop="subjects">
                    <div class="update-subject">
                        <div class="list">
                            <div v-for="item, index in updadeForm.subjects">
                                <el-form :model="item" ref="subjectRef" :rules="subjectRules">
                                    <el-form-item prop="debtorSubjectId">
                                        <el-select v-model="item.debtorSubjectId">
                                            <template #prefix>借方</template>
                                            <template #header>
                                                <input class="search-input" type="text" v-model="searchKey"
                                                    placeholder="请输入"><el-icon>
                                                    <Search />
                                                </el-icon>
                                            </template>
                                            <el-option
                                                v-for="subject in subjectChildList.filter(v => v.subjectName.indexOf(searchKey) != -1)"
                                                :label="subject.subjectName" :value="subject.subjectId" />
                                        </el-select>
                                    </el-form-item>
                                    <el-form-item prop="creditorSubjectId">
                                        <el-select v-model="item.creditorSubjectId">
                                            <template #prefix>贷方</template>
                                            <template #header>
                                                <input class="search-input" type="text" v-model="searchKey"
                                                    placeholder="请输入"><el-icon>
                                                    <Search />
                                                </el-icon>
                                            </template>
                                            <el-option
                                                v-for="subject in subjectChildList.filter(v => v.subjectName.indexOf(searchKey) != -1)"
                                                :label="subject.subjectName" :value="subject.subjectId" />
                                        </el-select>
                                    </el-form-item>
                                </el-form>
                                <img src="@/assets/images/del.png" alt="" @click="updadeForm.subjects.splice(index, 1)">
                            </div>
                        </div>
                        <div class="add">
                            <el-space
                                @click="updadeForm.subjects?.push({ debtorSubjectId: '', creditorSubjectId: '' })">
                                <el-icon>
                                    <CirclePlusFilled />
                                </el-icon>添加借方/贷方
                            </el-space>
                        </div>
                    </div>
                </el-form-item>
                <el-form-item label="备注说明" prop="remark">
                    <el-input type="textarea" placeholder="请输入" v-model="updadeForm.remark" @keyup.enter="getVoucherNum"
                        @blur="getVoucherNum"></el-input>
                    <div class="tip">
                        合计{{ voucherNum }}条凭证
                    </div>
                </el-form-item>
                <span class="tip">
                    功能说明 ：针对单据科目配置错误情况，可通过备注说明批量进行更改
                </span>
            </el-form>
            <template #footer>
                <div>
                    <el-button @click="updateVisible = false">取消</el-button>
                    <el-button type="primary" @click="updateComfirm">确定</el-button>
                </div>
            </template>
        </el-dialog>
        <el-dialog v-model="delVisible" :width="360" center align-center :show-close="false">
            <div class="modal-message">
                <el-icon>
                    <Warning />
                </el-icon>
                <div class="del-tip">确认删除该条记账记录？</div>
            </div>
            <template #footer>
                <div>
                    <el-button @click="delVisible = false">取消</el-button>
                    <el-button type="primary" @click="delRecord">确定</el-button>
                </div>
            </template>
        </el-dialog>
    </div>
</template>

<script setup>
import { ref, onMounted } from "vue";
import { RefreshRight, Search } from '@element-plus/icons-vue';
import { type } from "@/utils/config";
import { getList, getSubjectTree } from "@/apis/record";
import { getPartnerList, getList as getInvoices } from "@/apis/invoices";
import { getChild } from '@/utils/tree';
import { ElMessage } from 'element-plus';
import { add, edit, batchBack, exportRecord, del, updateSubject, getVoucherCount } from "@/apis/record";
import { slipType, slipUrl } from "@/utils/config"
import { useRouter } from "vue-router";
import exportExcel from "@/utils/exportExcel";

const router = useRouter();
const updateVisible = ref(false);
const toPath = (query) => {
    const path = slipUrl(query.type);
    if (path) {
        const routeInfo = router.resolve({
            path,
            query
        });
        const url = routeInfo.href;
        window.open(url, '_blank')
    }
}
const visible = ref(false);
const query = ref({
    current: 1,
    size: 10
})
const params = ref({
    source: undefined,
    status: 0
});

const subjectRef = ref(null);
const updadeFormRef = ref(null);
const updadeForm = ref({
    subjects: []
})
const searchKey = ref('');
const data = ref([])
const total = ref(0);
const isNew = ref(false);
const form = ref({
    borrow: [],
    loan: []
})
const formRef = ref(null);
const borrowRef = ref(null);
const loanRef = ref(null);
const reset = () => {
    params.value = {};
    init()
}
const resetUpdate = () => {
    updadeForm.value = { subjects: [] };
    voucherNum.value = 0;
    updadeFormRef.value.resetFields();
}
const collaboratorsList = ref([]);//合作方列表

const subjectChildList = ref([]);//科目
const slipList = ref([])

const checked = ref([])
const validator = (value, rules, callback) => {
    if ((!form.value.loan.length) && (!form.value.borrow.length)) {
        callback('请选择科目')
    } else {
        callback()
    }
}
const updateValidator = (value, rules, callback) => {
    if (!updadeForm.value.subjects.length) {
        callback('请选择科目')
    } else {
        callback()
    }
}
/**
 * 关闭的回调
 */
const close = () => {
    formRef.value.resetFields();
    form.value = {
        borrow: [],
        loan: []
    }
}
const voucherNum = ref(0)
/**
 * 获取凭证数量
 */
const getVoucherNum = async () => {
    const res = await getVoucherCount({ remark: updadeForm.value.remark });
    voucherNum.value = res.data;
}
const rules = {
    partnerId: [{ required: true, message: '请选择合作商', trigger: 'change' }],
    remark: [{ required: true, message: '请输入备注' }, { max: 100, message: '备注说明不能超过100个字符', trigger: 'blur' }],
    subjects: [{ validator, trigger: 'blur' }],
    slipId: [{ max: 30, message: '单号不能超过30个字符', trigger: 'blur' }]
}
const subjectRules = {
    money: [{ required: true, message: '请输入金额', trigger: 'blur' }, { pattern: /^[0-9]+(\.[0-9]{1,2})?$/, message: '请输入正确的金额', trigger: 'blur' }],
    subjectId: [{ required: true, message: '请选择科目', trigger: 'change' }],
    debtorSubjectId: [{ required: true, message: '请选择借方科目', trigger: 'change' }],
    creditorSubjectId: [{ required: true, message: '请选择贷方科目', trigger: 'change' }],
}
const updadeRules = {
    remark: [{ required: true, message: '请输入备注', trigger: 'blur' }, { max: 100, message: '备注说明不能超过100个字符', trigger: 'blur' }],
    subjects: [{ validator: updateValidator, trigger: 'blur' }, { required: true, message: '请选择科目', trigger: 'blur' }]
}
/**
 * 获取单据列表
 */
const getSlipList = async () => {
    if (form.value.slipType) {
        const res = await getInvoices({ current: 1, size: 10000 }, { serviceType: form.value.slipType, partnerId: form.value.partnerId })
        slipList.value = res.data.list;
    }
}
/**
 * 
 */
const mergeId = (tree) => {
    tree.forEach(item => {
        if (item.children && item.children.length) {
            mergeId(item.children)
        } else {
            item.name = item.name + '(' + item.partnerId + ')'
        }
    });
    return tree;
}
const resetKey = () => {
    params.value.partnerType = '';
    params.value.partnerValue = '';
    init()
}
const inquire = (type, key) => {
    let t = setTimeout(async () => {
        const res = await getPartnerList(type, key);
        collaboratorsList.value = mergeId(res.data);
        clearTimeout(t);
    }, 200);
}
/**
 * 输入合作商关键词的方法
 */
const remoteMethod = (key) => {
    if (key !== '') {
        inquire(form.value.partnerType, key)
    } else {
        collaboratorsList.value = []
    }
}
/**
 * 打开弹窗
 */
const openModal = async (item) => {
    if (item.loanedBillId) {
        isNew.value = false;
        const partnerType = Number(item.partnerType);
        const borrow = item.subjects.filter(v => v.type == 1);
        const loan = item.subjects.filter(v => v.type == 2);
        form.value = { ...JSON.parse(JSON.stringify({ ...item, partnerType, borrow, loan })) };
        const res = await getPartnerList(form.value.partnerType);
        collaboratorsList.value = mergeId(res.data);
        await getSlipList();
    } else {
        isNew.value = true;
    }
    visible.value = true;
}
const delDetail = ref({});
const delVisible = ref(false);
const openDel = (row) => {
    delDetail.value = { ...row };
    delVisible.value = true;
}
const delRecord = async () => {
    await del(delDetail.value.loanedBillId);
    ElMessage.success('删除成功');
    init();
    delVisible.value = false;
}

/**
 * 重写参数
 */
const getparamData = () => {
    const paramsData = { ...params.value };
    const subjectId = paramsData.subjectId ? paramsData.subjectId[paramsData.subjectId.length - 1] : undefined;
    if (paramsData.date) {
        paramsData.addDateStart = paramsData.date[0] + ' ' + '00:00:00';
        paramsData.addDateEnd = paramsData.date[1] + ' ' + '23:59:59';
        paramsData.addDateStart = paramsData.date[0] + ' ' + '00:00:00';
        paramsData.addDateEnd = paramsData.date[1] + ' ' + '23:59:59';
    }
    delete paramsData.date;
    return { ...paramsData, subjectId };
}
/**
 * 初始化
 */
const init = async () => {
    const res = await getList(query.value, getparamData());
    data.value = res.data.list;
    total.value = res.data.total;
}
/**
 * 获取科目树
 */
const getTree = async () => {
    const res = await getSubjectTree();
    subjectChildList.value = getChild(res.data, 'children')
}
/**
 * 批量记账
 */
const batchAccounting = async () => {
    if (!checked.value.length) return ElMessage.error('请选择要操作的数据');
    await batchBack({ loanedBillIds: checked.value });
    ElMessage.success('操作成功');
    init();
}
/**
 * 校验新建表单
 */
const verify = async () => {
    let arr = [];
    arr.push(new Promise((resolve) => {
        formRef.value.validate(valid => {
            resolve(valid)
        })
    }));
    if (form.value.borrow.length) {
        borrowRef.value.forEach(v => {
            arr.push(new Promise((resolve) => {
                v.validate(valid => {
                    resolve(valid)
                })
            }));
        })
    }
    if (form.value.loan.length) {
        loanRef.value.forEach(v => {
            arr.push(new Promise((resolve) => {
                v.validate(valid => {
                    console.log(valid)
                    resolve(valid)
                })
            }));
        })
    }
    const res = await Promise.all(arr);
    return res.every(item => item)
}

const updateVerify = async () => {
    let arr = [];
    arr.push(new Promise((resolve) => {
        updadeFormRef.value.validate(valid => {
            resolve(valid)
        })
    }));
    if (updadeForm.value.subjects.length) {
        subjectRef.value.forEach(v => {
            arr.push(new Promise((resolve) => {
                v.validate(valid => {
                    resolve(valid)
                })
            }));
        })
    }
    const res = await Promise.all(arr);
    return res.every(item => item)
}
/**
 * 调整科目
 */
const updateComfirm = async () => {
    if (await updateVerify()) {
        const res = await updateSubject(updadeForm.value);
        if (res.code == 200) {
            init();
            ElMessage.success('操作成功');
            updateVisible.value = false;
        }

    }
}
/**
 * 导出
 */
const exportData = async () => {
    const res = await exportRecord(getparamData());
    exportExcel(res, '未记账')
}
/**
 * 添加/编辑
 */
const comfirm = async () => {
    const close = (res) => {
        if (res.code == 200) {
            visible.value = false;
            ElMessage.success('添加成功');
            init()
        }
    }
    if (await verify()) {
        let subjects = [...form.value.borrow.map(v => ({ ...v, type: 1 })), ...form.value.loan.map(v => ({ ...v, type: 2 }))];
        const paramsData = { ...form.value, subjects };
        delete paramsData.borrow;
        delete paramsData.loan;
        delete paramsData.slipType;
        if (isNew.value) {
            const res = await add(paramsData);
            close(res)
        } else {
            const res = await edit(paramsData);
            close(res)
        }

    }
}
/**
 * 批量
 */
const handleSelectionChange = (value) => {
    checked.value = value.map(v => v.loanedBillId)
}
onMounted(() => {
    init();
    getTree()
})
</script>

<style lang="scss" scoped>
@import '../index.scss';
</style>